package com.yaiys.thread;

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
 * 1. Semaphore 是什么？
 * Semaphore 字面意思是信号量的意思，它的作用是控制访问特定资源的线程数目，底层依赖AQS的状态State，是在生产当中比较常用的一个工具类。
 * 2. 怎么使用 Semaphore？
 * 2.1 构造方法
 * public Semaphore(int permits)
 * public Semaphore(int permits, boolean fair)
 * permits 表示许可线程的数量
 * fair 表示公平性，如果这个设为 true 的话，下次执行的线程会是等待最久的线程
 * 2.2 重要方法
 * public void acquire() throws InterruptedException
 * public void release()
 * tryAcquire（int args,long timeout, TimeUnit unit）
 * acquire() 表示阻塞并获取许可
 * release() 表示释放许可
 * 2.3 基本使用
 * 2.3.1 需求场景
 * 资源访问，服务限流(Hystrix里限流就有基于信号量方式)。
 * **/
public class SemaphoreRunner {
    public static void main(String[] args) throws InterruptedException {
        /**
         * 此类场景适应与限流场景
         * **/
        Semaphore semaphore = new Semaphore(20);
        for (int i = 0; i < 100; i++) {
            Thread.sleep(new Random().nextInt(3000));
            new Thread(new Task(semaphore, "yangguo+" + i)).start();
        }
    }

    static class Task extends Thread {
        Semaphore semaphore;

        public Task(Semaphore semaphore, String tname) {
            this.semaphore = semaphore;
            this.setName(tname);
        }

        public void run() {
            try {
                semaphore.acquire();
                //超时3秒返回false
                semaphore.tryAcquire(3, TimeUnit.SECONDS);
                System.out.println(Thread.currentThread().getName() + ":一秒钟一次() at time:" + System.currentTimeMillis());
                Thread.sleep(3000);
                semaphore.release();
                System.out.println(Thread.currentThread().getName() + ":释放资源() at time:" + System.currentTimeMillis());

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}